package zcj.stu.C46;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

@Configuration
public class C46 {
    public static void main(String[] args) throws Exception{
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(C46.class);
        DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();

        ContextAnnotationAutowireCandidateResolver resolver=new ContextAnnotationAutowireCandidateResolver();
        resolver.setBeanFactory(beanFactory);
        //拿到@value里面的值
        Field home = Bean1.class.getDeclaredField("home");
        test1(context, resolver, home);
        Field age=Bean1.class.getDeclaredField("age");
        test2(context,resolver,age);
        Field bean3 = Bean2.class.getDeclaredField("bean3");
        test3(context,resolver,bean3);
        Field value = Bean4.class.getDeclaredField("value");
        System.out.println("test4...");
        test4(context,resolver,value);
    }
    private static void test4(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field home) {
        DependencyDescriptor dd1 = new DependencyDescriptor(home, false);
        String value = (String) resolver.getSuggestedValue(dd1);
        //解析${}
        value = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(value.getClass());
        System.out.println(value);
        //解析#{}
        Object bean3 = context.getBeanFactory().getBeanExpressionResolver().evaluate(value, new BeanExpressionContext(context.getBeanFactory(),null));
        Object convert = context.getBeanFactory().getTypeConverter().convertIfNecessary(bean3, dd1.getDependencyType());
        System.out.println(convert.getClass());
        System.out.println(convert);
    }
    private static void test3(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field home) {
        DependencyDescriptor dd1 = new DependencyDescriptor(home, false);
        String value = (String) resolver.getSuggestedValue(dd1);
        //解析${}
        value = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(value.getClass());
        System.out.println(value);
        //解析#{}
        Object bean3 = context.getBeanFactory().getBeanExpressionResolver().evaluate(value, new BeanExpressionContext(context.getBeanFactory(),null));
        Object convert = context.getBeanFactory().getTypeConverter().convertIfNecessary(bean3, dd1.getDependencyType());
        System.out.println(convert.getClass());
        System.out.println(convert);
    }
    private static void test2(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field home) {
        DependencyDescriptor dd1 = new DependencyDescriptor(home, false);
        String value = (String) resolver.getSuggestedValue(dd1);
        //解析${}
        value = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(value.getClass());
        System.out.println(value);
        Object convert = context.getBeanFactory().getTypeConverter().convertIfNecessary(value, dd1.getDependencyType());
        System.out.println(convert.getClass());
        System.out.println(convert);
    }
    private static void test1(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field home) {
        DependencyDescriptor dd1 = new DependencyDescriptor(home, false);
        String value = (String) resolver.getSuggestedValue(dd1);
        //解析${}
        value = context.getEnvironment().resolvePlaceholders(value);
        System.out.println(value);
    }
    static class Bean1{
        @Value("${JAVA_HOME}")
        private String home;
        @Value("18")
        private int age;
    }

    static class Bean2{
        @Value("#{@bean3}")//根据名字注入bean
        private Bean3 bean3;
    }
    @Component("bean3")
    static class Bean3{}
    static class Bean4{
        @Value("#{'hello'+'${JAVA_HOME}'}")
        private String value;
    }
}
